package com.magic.cd.core;

import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;

/**
 * MyCatPackage
 * 解析和读取
 * 根据MySQL协议数据类型定制Packet，
 * 一个读取对应着一个写入
 * */
public class MiniCatPacket {
	private int maxLength=0;
	private int index = 0;
	private byte[] pkg;
	
	public MiniCatPacket(int len){
		maxLength = len;
		pkg = new byte[len];
	}
	
	public MiniCatPacket(byte[] data){
		maxLength = data.length;
		pkg = data;
	}
	
	/**
	 * 获取包的长度
	 * */
	public int getMaxLength(){
		return maxLength;
	}
	
	/**
	 * 获取包的内容
	 * */
	public byte[] getBytePacket() {
		return pkg;
	}
	
	/**
	 * 设置Packet需要跳过的字节数
	 * */
	public void setSkipIndex(int len){
		index+=len;
	}
	
	//--------------------写入协议数据-----------------------
	
	/**
	 * 写入byte(1位)
	 * */
	public void writeByte(byte data){
		pkg[index++] = data;
	}
	
	/**
	 * 写入int(2位)
	 * */
	public void writeInt(int data){
		pkg[index++] = (byte) (data & 0xff);
		pkg[index++] = (byte) (data >>> 8);
	}
	
	/**
	 * 写入long(4位)
	 * */
	public void writeLong(long data){
		pkg[index++] = (byte) (data & 0xff);
		pkg[index++] = (byte) (data >>> 8);
		pkg[index++] = (byte) (data >>> 16);
		pkg[index++] = (byte) (data >>> 24);
	}
	
	/**
	 * 写入指定的byte[] (len位)
	 * */
	public void writeBytesNoNull(byte[] bytes) {
		int len = bytes.length;
		System.arraycopy(bytes, 0,pkg, index, len);
		index+= len;
	}
	
	/**
	 * 写入string(length+1位)
	 * 多的1位是0，标识字符串写入结束
	 * */
	public void writeString(String data){
		int len = data.length();
		try {
			System.arraycopy(data.getBytes("UTF-8"), 0, pkg, index, len);
		} catch (UnsupportedEncodingException e) {
			new RuntimeException(e.getMessage());
		}
		index += len+1;
	}
	
	//---------------------读取协议数据-----------------------
	/**
	 * 读byte(1位字节)
	 * */
	public byte readByte() {
		return pkg[index++];
	}
	
	/**
	 * 读int(2位字节)
	 * */
	public int readInt() {
		return (pkg[index++] & 0xff) | ((pkg[index++] & 0xff) << 8);
	}
	
	/**
	 * 读long(4位字节)
	 * */
	public long readLong() {
		return ((long) pkg[index++] & 0xff)
			| (((long) pkg[index++] & 0xff) << 8)
			| ((long) (pkg[index++] & 0xff) << 16)
			| ((long) (pkg[index++] & 0xff) << 24);
	}
	
	/**
	 * 读取字符串类型数据(指定格式)
	 * 读取时注意遇到0表示当前字符串类型读取完毕
	 * */
	public String readString(String encoding) {
		int i = index;
		int len = 0;

		while ((i<maxLength)&&(this.pkg[i]!=0)) {
			len++;
			i++;
		}
		
		try {
			Charset cs = Charset.forName(encoding);
			return cs.decode(ByteBuffer.wrap(pkg,index,len)).toString();
		} catch (Exception e) {
			throw new RuntimeException(e.getMessage());
		} finally {
			index += (len + 1); 
		}
	}
	
	/**
	 * 读取字符串类型数据
	 * */
	public String readString(String encoding,int len) {
		try {
			Charset cs = Charset.forName(encoding);
			return cs.decode(ByteBuffer.wrap(pkg,index,len)).toString();
		} catch (Exception e) {
			throw new RuntimeException(e.getMessage());
		} finally {
			index += len; 
		}
	}
	//---------------结束---------------
}
